﻿namespace TriangleGames.TrainResEditor
{
    using TriangleGames.TrainRes;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using UnityEditor;
    using UnityEngine;

    public class CustomActionWizard : EditorWindow
    {
        private string[] actionCategories;
        private string actionFolder = "Animation";
        private string actionName = "";
        private string code;
        private Vector2 controlsScrollPosition;
        private string customCategory = "";
        private bool draggingPreviewDivider;
        private string errorString;
        private bool folderSameAsCategory = true;
        private string fullFileName;
        private bool handlesOnEnter = true;
        private bool handlesOnExit;
        private bool handlesOnFixedUpdate;
        private bool handlesOnLateUpdate;
        private bool handlesOnUpdate;
        private bool hasCustomErrorChecker;
        private bool isValid;
        private string localAssetFilename;
        private Rect previewDividerRect;
        private float previewHeight;
        private Vector2 previewScrollPosition;
        private string rootFolder = "TrainRes/Actions/";//fsr
        private int selectedCategory;
        private string tooltip = "";

        private void BuildCustomAction()
        {
            this.code = "using UnityEngine;\nusing TriangleGames.Train;\n\n";//fsr
            if (string.IsNullOrEmpty(this.customCategory))
            {
                this.code = this.code + "[ActionCategory(ActionCategory." + this.actionCategories[this.selectedCategory] + ")]\n";
            }
            else
            {
                this.code = this.code + "[ActionCategory(\"" + this.customCategory + "\")]\n";
            }
            if (!string.IsNullOrEmpty(this.tooltip))
            {
                this.code = this.code + "[Tooltip(\"" + this.tooltip + "\")]\n";
            }
            this.code = this.code + "public class " + this.actionName + " : FsmStateAction\n{\n\n";
            if (this.handlesOnEnter)
            {
                this.code = this.code + BuildOverrideMethod("void OnEnter()", "进入状态时运行的代码.", this.HasUpdateMethod() ? "" : "Finish();");
            }
            if (this.handlesOnUpdate)
            {
                this.code = this.code + BuildOverrideMethod("void OnUpdate()", "每帧都运行的代码.", "");
            }
            if (this.handlesOnFixedUpdate)
            {
                this.code = this.code + BuildOverrideMethod("void OnFixedUpdate()", "", "");
            }
            if (this.handlesOnLateUpdate)
            {
                this.code = this.code + BuildOverrideMethod("void OnLateUpdate()", "", "");
            }
            if (this.handlesOnExit)
            {
                this.code = this.code + BuildOverrideMethod("void OnExit()", "离开状态时运行的代码.", "");
            }
            if (this.hasCustomErrorChecker)
            {
                this.code = this.code + BuildOverrideMethod("string ErrorCheck()", "检查动作的错误.", "// 如果没有错误则返回null.\n\nreturn null;");
            }
            this.code = this.code + "\n}\n";
        }

        private static string BuildOverrideMethod(string methodName, [Optional, DefaultParameterValue("")] string comment, [Optional, DefaultParameterValue("")] string body)
        {
            string str = "";
            if (!string.IsNullOrEmpty(comment))
            {
                str = str + "\t// " + comment + "\n";
            }
            return (((str + "\tpublic override " + methodName + "\n\t{\n") + "\t\t" + body.Replace("\n", "\n\t\t") + "\n") + "\t}\n\n");
        }

        private static void ControlGroup(string title)
        {
            GUILayout.Space(10f);
            GUILayout.Label(title, EditorStyles.boldLabel, new GUILayoutOption[0]);
            GUILayout.Space(5f);
        }

        private void CopyCodeToClipboard()
        {
            EditorGUIUtility.systemCopyBuffer = this.code;
        }

        private void HandleDragPreviewDivider()
        {
            switch (Event.current.type)
            {
                case EventType.MouseDown:
                    if (this.previewDividerRect.Contains(Event.current.mousePosition))
                    {
                        this.draggingPreviewDivider = true;
                    }
                    break;

                case EventType.MouseUp:
                    this.draggingPreviewDivider = false;
                    EditorPrefs.SetFloat("TrainRes.CustomActionWizard.PreviewHeight", this.previewHeight);
                    break;

                default:
                    if (this.draggingPreviewDivider && Event.current.isMouse)
                    {
                        this.previewHeight = (base.position.height - Event.current.mousePosition.y) - 60f;
                        base.Repaint();
                    }
                    break;
            }
            this.previewHeight = Mathf.Clamp(this.previewHeight, 40f, base.position.height - 200f);
        }

        private bool HasUpdateMethod()
        {
            if (!this.handlesOnUpdate && !this.handlesOnFixedUpdate)
            {
                return this.handlesOnLateUpdate;
            }
            return true;
        }

        private bool IsValidSetup()
        {
            this.errorString = "";
            if (string.IsNullOrEmpty(this.actionName))
            {
                this.errorString = this.errorString + "请输入有效的动作名称.\n";
            }
            if (File.Exists(this.fullFileName))
            {
                this.errorString = this.errorString + "动作文件已经存在!\n";
            }
            return (this.errorString == "");
        }

        private void OnEnable()
        {
            base.title = "定制动作";
            this.rootFolder = EditorPrefs.GetString("TrainRes.CustomActionWizard.RootFolder", "TrainRes/Actions/");
            this.previewHeight = EditorPrefs.GetFloat("TrainRes.CustomActionWizard.PreviewHeight", 200f);
            base.wantsMouseMove = true;
            base.autoRepaintOnSceneChange = true;
            List<string> list = Enumerable.ToList<string>(Enum.GetNames(typeof(ActionCategory)));
            list.Sort();
            this.actionCategories = list.ToArray();
            if (base.position.height < 200f)
            {
                base.position = new Rect(base.position.x, base.position.y, base.position.width, 600f);
            }
            base.minSize = new Vector2(500f, 200f);
            this.UpdateGUI();
        }

        private void OnFocus()
        {
            this.UpdateGUI();
            this.draggingPreviewDivider = false;
        }

        private void OnGUI()
        {
            if (!FsmEditorStyles.IsInitialized())
            {
                FsmEditorStyles.Init();
            }
            FsmEditorGUILayout.ToolWindowLargeTitle(this, "自定义动作向导");
            EditorGUIUtility.LookLikeControls(200f);
            this.HandleDragPreviewDivider();
            this.controlsScrollPosition = EditorGUILayout.BeginScrollView(this.controlsScrollPosition, new GUILayoutOption[0]);
            EditorGUI.indentLevel = 1;
            ControlGroup("名称和描述");
            this.actionName = EditorGUILayout.TextField("动作名称", this.actionName, new GUILayoutOption[0]);
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            EditorGUILayout.LabelField("描述", "", new GUILayoutOption[] { GUILayout.MinWidth(196f), GUILayout.MaxWidth(196f) });
            this.tooltip = EditorGUILayout.TextArea(this.tooltip, new GUILayoutOption[0]);
            GUILayout.EndHorizontal();
            ControlGroup("类别");
            GUI.enabled = string.IsNullOrEmpty(this.customCategory);
            this.selectedCategory = EditorGUILayout.Popup("选择类别", this.selectedCategory, this.actionCategories, new GUILayoutOption[0]);
            GUI.enabled = true;
            this.customCategory = EditorGUILayout.TextField("定制类别", this.customCategory, new GUILayoutOption[0]);
            ControlGroup("代码存放目录");
            this.rootFolder = EditorGUILayout.TextField("根目录", this.rootFolder, new GUILayoutOption[0]);
            GUI.enabled = !this.folderSameAsCategory;
            this.actionFolder = EditorGUILayout.TextField("动作目录", this.actionFolder, new GUILayoutOption[0]);
            GUI.enabled = true;
            this.folderSameAsCategory = EditorGUILayout.Toggle("和类别一样", this.folderSameAsCategory, new GUILayoutOption[0]);
            ControlGroup("添加方法");
            this.handlesOnEnter = EditorGUILayout.Toggle("OnEnter", this.handlesOnEnter, new GUILayoutOption[0]);
            this.handlesOnUpdate = EditorGUILayout.Toggle("OnUpdate", this.handlesOnUpdate, new GUILayoutOption[0]);
            this.handlesOnFixedUpdate = EditorGUILayout.Toggle("OnFixedUpdate", this.handlesOnFixedUpdate, new GUILayoutOption[0]);
            this.handlesOnLateUpdate = EditorGUILayout.Toggle("OnLateUpdate", this.handlesOnLateUpdate, new GUILayoutOption[0]);
            this.handlesOnExit = EditorGUILayout.Toggle("OnExit", this.handlesOnExit, new GUILayoutOption[0]);
            this.hasCustomErrorChecker = EditorGUILayout.Toggle("Custom Error Checker", this.hasCustomErrorChecker, new GUILayoutOption[0]);
            EditorGUILayout.EndScrollView();
            if (!this.isValid)
            {
                FsmEditorGUILayout.Divider(new GUILayoutOption[0]);
                GUILayout.Box(this.errorString, FsmEditorStyles.ErrorBox, new GUILayoutOption[0]);
            }
            GUILayout.BeginHorizontal(EditorStyles.toolbar, new GUILayoutOption[0]);
            GUILayout.Label("代码预览", EditorStyles.miniBoldLabel, new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            if (Event.current.type == EventType.Repaint)
            {
                this.previewDividerRect = GUILayoutUtility.GetLastRect();
            }
            EditorGUIUtility.AddCursorRect(this.previewDividerRect, MouseCursor.ResizeVertical);
            this.previewScrollPosition = EditorGUILayout.BeginScrollView(this.previewScrollPosition, new GUILayoutOption[] { GUILayout.MinHeight(this.previewHeight) });
            GUILayout.Label(this.code, new GUILayoutOption[0]);
            EditorGUILayout.EndScrollView();
            FsmEditorGUILayout.Divider(new GUILayoutOption[0]);
            GUILayout.Label("文件: Assets/" + this.localAssetFilename, new GUILayoutOption[0]);
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUI.enabled = this.isValid;
            if (GUILayout.Button("保存", new GUILayoutOption[0]))
            {
                this.SaveCustomAction();
                GUIUtility.ExitGUI();
            }
            else
            {
                GUI.enabled = true;
                if (GUILayout.Button(new GUIContent("查找文件", "在工程视图定位文件."), new GUILayoutOption[] { GUILayout.MaxWidth(100f) }))
                {
                    this.PingScriptFile();
                }
                if (GUILayout.Button(new GUIContent("复制代码", "复制生成的代码到粘贴板."), new GUILayoutOption[] { GUILayout.MaxWidth(100f) }))
                {
                    this.CopyCodeToClipboard();
                }
                GUILayout.EndHorizontal();
                GUILayout.Space(10f);
                EditorGUI.indentLevel = 0;
                if (GUI.changed)
                {
                    this.UpdateGUI();
                    GUIUtility.ExitGUI();
                }
            }
        }

        private void PingScriptFile()
        {
            EditorGUIUtility.PingObject(AssetDatabase.LoadMainAssetAtPath("Assets/" + this.localAssetFilename));
        }

        private void SaveCustomAction()
        {
            Debug.Log("创建自定义动作: " + this.fullFileName);
            string directoryName = Path.GetDirectoryName(this.fullFileName);
            if (string.IsNullOrEmpty(directoryName))
            {
                Debug.LogError("无效路径: " + this.fullFileName);
            }
            else
            {
                try
                {
                    if (!Directory.Exists(directoryName))
                    {
                        Directory.CreateDirectory(directoryName);
                    }
                }
                catch (Exception)
                {
                    Debug.LogError("不能创建目录: " + directoryName);
                    return;
                }
                using (StreamWriter writer = new StreamWriter(this.fullFileName))
                {
                    writer.Write(this.code);
                    writer.Close();
                }
                AssetDatabase.Refresh();
                this.PingScriptFile();
            }
        }

        private void UpdateGUI()
        {
            this.previewHeight = Mathf.Clamp(this.previewHeight, 40f, base.position.height - 190f);
            EditorPrefs.SetString("TrainRes.CustomActionWizard.RootFolder", this.rootFolder);
            if (this.folderSameAsCategory)
            {
                this.actionFolder = string.IsNullOrEmpty(this.customCategory) ? this.actionCategories[this.selectedCategory] : this.customCategory;
            }
            string str = Path.Combine(this.rootFolder, this.actionFolder);
            this.localAssetFilename = Path.Combine(str, this.actionName + ".cs");
            this.fullFileName = Path.Combine(Application.dataPath, this.localAssetFilename);
            this.localAssetFilename = this.localAssetFilename.Replace(@"\", "/");
            this.fullFileName = this.fullFileName.Replace(@"\", "/");
            this.BuildCustomAction();
            this.isValid = this.IsValidSetup();
        }
    }
}

